package com.lmk.ms.common.mvc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lmk.ms.common.constants.DbDelFlagEnum;
import com.lmk.ms.common.constants.DbStatusEnum;
import com.lmk.ms.common.dto.db.PageResult;
import com.lmk.ms.common.dto.db.QueryParams;
import com.lmk.ms.common.dto.db.Search;
import com.lmk.ms.common.dto.db.Sort;
import com.lmk.ms.common.dto.mvc.IdParameter;
import com.lmk.ms.common.dto.mvc.Meta;
import com.lmk.ms.common.entity.PkEntity;
import com.lmk.ms.common.entity.RecordEntity;
import com.lmk.ms.common.mvc.service.BaseService;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.List;

/**
 * 基础服务的实现
 *
 * @author laomake@hotmail.com
 * @version 1.0
 * @date 2021/07/12
 */
@Slf4j
public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends PkEntity> extends ServiceImpl<M, T> implements BaseService<T> {

    @Override
    public Meta loadMetaInfo() {
        return new Meta();
    }

    @Override
    public PageResult<T> pageList(QueryParams queryParams, List<Search> searchList, List<Sort> sortList) {
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        for (Search search : searchList) {
            switch (search.getOperator()) {
                case eq:
                    wrapper.eq(search.getName(), search.getValue());
                    break;
                case notEq:
                    wrapper.ne(search.getName(), search.getValue());
                    break;
                case like:
                    wrapper.like(search.getName(), search.getValue());
                    break;
                case gt:
                    wrapper.gt(search.getName(), search.getValue());
                    break;
                case lt:
                    wrapper.lt(search.getName(), search.getValue());
                    break;
                case isNull:
                    wrapper.isNull(search.getName());
                    break;
                case notNull:
                    wrapper.isNull(false,  search.getName());
                    break;
            }
        }

        // 排序参数
        for (Sort sort : sortList) {
            if ("ASC".equals(sort.getType())) {
                wrapper.orderByAsc(sort.getColumn());
            } else {
                wrapper.orderByDesc(sort.getColumn());
            }
        }

        // 设置查询字段
        wrapper.select(queryParams.getColumns());

        Page<T> page = new Page<>(queryParams.getPage(), queryParams.getSize());
        getBaseMapper().selectPage(page, wrapper);

        return new PageResult<>(page);
    }

    @Override
    public Boolean changeDbStatus(IdParameter parameter) {

        // 对于不存在的对象，或已经删除的对象，不进行任何操作
        Serializable id = parameter.getId();
        T entity = getById(id);
        if(entity == null){
            return false;
        }

        if(entity instanceof RecordEntity<?>){
            RecordEntity re = (RecordEntity) entity;
            if(re.getDelFlag() == DbDelFlagEnum.YES || re.getStatus() == DbStatusEnum.REMOVE){
                return false;
            }

            DbStatusEnum status = re.getStatus();
            if(status == DbStatusEnum.ENABLE){
                status = DbStatusEnum.DISABLE;
            } else if (status == DbStatusEnum.DISABLE) {
                status = DbStatusEnum.ENABLE;
            }

            UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id).set("status", status.getValue());
            return baseMapper.update(null, updateWrapper) > 0;
        } else {
            // 对于不是RecordEntity类的对象，无法判断是否包含status字段，不进行任何操作
            return false;
        }
    }
}
